package com.bzchao.doublecamera.utils;

import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.util.Log;

import java.nio.ByteBuffer;
import java.text.SimpleDateFormat;
import java.util.Date;

public class BitmapUtils {
    private static final boolean debug = false;

    private static final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss EEEE");

    /**
     * 添加时间水印
     *
     * @param mBitmap
     * @return
     */
    public static Bitmap addTimeWatermark(Bitmap mBitmap) {
        //获取原始图片与水印图片的宽与高
        int mBitmapWidth = mBitmap.getWidth();
        int mBitmapHeight = mBitmap.getHeight();
        Bitmap mNewBitmap = Bitmap.createBitmap(mBitmapWidth, mBitmapHeight, Bitmap.Config.ARGB_8888);
        Canvas mCanvas = new Canvas(mNewBitmap);
        //向位图中开始画入MBitmap原始图片
        mCanvas.drawBitmap(mBitmap, 0, 0, null);
        //添加文字
        Paint mPaint = new Paint();
        String dataStr = dateFormat.format(new Date());
        mPaint.setColor(Color.RED);
        mPaint.setTextSize(18);
        //水印的位置坐标
        mCanvas.drawText("双摄测试 " + dataStr, (mBitmapWidth * 1) / 10, (mBitmapHeight * 14) / 15, mPaint);
        mCanvas.save();
        mCanvas.restore();

        return mNewBitmap;
    }

    /**
     * 将图片转为bitmap
     *
     * @param res
     * @param id
     * @param opts
     * @return
     */
    public static Bitmap getBitmap(Resources res, int id, BitmapFactory.Options opts) {
        Bitmap bitmap = BitmapFactory.decodeResource(res, id, opts);
        return bitmap;
    }

    /**
     * 叠加两张图片
     *
     * @param background 背景图片
     * @param foreground 前置图片
     * @return
     */
    public static Bitmap toConformBitmap(Bitmap background, Bitmap foreground) {
        if (background == null) {
            return null;
        }
        TimeStaticUtils timeStaticUtils = TimeStaticUtils.start();
        // 取得想要缩放的matrix参数
        Matrix matrix = new Matrix();
        matrix.postRotate(90f);


        // 得到新的图片
        Bitmap newBackground = Bitmap.createBitmap(background, 0, 0, background.getWidth(), background.getHeight(), matrix, true);

        long runTime = timeStaticUtils.endAndGetRunTime();
        if (debug) {
            //时间最长750-800ms(4000*3000)
            Log.i("toConform_new_bg", String.format("处理时间 %d ms", runTime));
        }

        TimeStaticUtils timeStaticUtils2 = TimeStaticUtils.start();
        // 取得想要缩放的matrix参数
        Matrix matrix2 = new Matrix();
        matrix2.postRotate(270f);
        //镜像水平翻转,前置摄像头的图片
        matrix2.postScale(-1, 1);
        // matrix2.postScale(0.5f, 0.5f);
        // 得到新的图片
        Bitmap newForeground = Bitmap.createBitmap(foreground, 0, 0, foreground.getWidth(), foreground.getHeight(), matrix2, true);

        long runTime2 = timeStaticUtils2.endAndGetRunTime();
        if (debug) {
            //300ms
            Log.i("toConform_new_fore", String.format("处理时间 %d ms", runTime2));
        }

        TimeStaticUtils timeStaticUtils3 = TimeStaticUtils.start();
        Canvas canvas = new Canvas(newBackground);
        //draw fg into 在 0，0坐标开始画入fg ，可以从任意位置画入
        canvas.drawBitmap(newForeground, 0, 0, null);
        //save all clip 保存
        canvas.save();
        //stor 存储
        canvas.restore();
        long runTime3 = timeStaticUtils3.endAndGetRunTime();
        if (debug) {
            //4ms
            Log.i("toConform_canvas", String.format("处理时间 %d ms", runTime3));
        }
        return newBackground;
    }


    /**
     * 叠加两张图片
     *
     * @param background 背景图片
     * @param foreground 前置图片
     * @return
     */
    public static Bitmap toConformBitmap2(Bitmap background, Bitmap foreground) {
        if (background == null) {
            return null;
        }
        // 取得想要缩放的matrix参数
        Matrix matrix = new Matrix();
        matrix.postRotate(90f);
        Bitmap newBackground = Bitmap.createBitmap(background, 0, 0, background.getWidth(), background.getHeight(), matrix, true);

        // 取得想要缩放的matrix参数
        Matrix matrix2 = new Matrix();
        matrix2.postRotate(270f);
        //镜像水平翻转,前置摄像头的图片
        matrix2.postScale(-1, 1);
        // matrix2.postScale(0.5f, 0.5f);
        // 得到新的前置图片（已经缩小了）
        Bitmap newForeground = Bitmap.createBitmap(foreground, 0, 0, foreground.getWidth(), foreground.getHeight(), matrix2, true);

        Canvas canvas = new Canvas(newBackground);
        //draw fg into 在 0，0坐标开始画入fg ，可以从任意位置画入
        canvas.drawBitmap(newForeground, 0, 0, null);
        //save all clip 保存
        canvas.save();
        //stor 存储
        canvas.restore();
        return newBackground;
    }

    /**
     * Writes Image data into a {@code ByteBuffer}.
     *
     * @return
     */
    public static ByteBuffer bitmapToByteBuffer(Bitmap bitmap) {
        ByteBuffer buf = ByteBuffer.allocate(bitmap.getByteCount());
        bitmap.copyPixelsToBuffer(buf);
        return buf;
    }

    public static Bitmap bufferToBitmap(ByteBuffer byteBuffer) {
        byte[] bytes = new byte[byteBuffer.remaining()];
        byteBuffer.get(bytes);
        Bitmap temp = BitmapFactory.decodeByteArray(bytes, 0, bytes.length, null);
        return temp;
    }

    public static Bitmap bufferToBitmap8888(ByteBuffer byteBuffer, int width, int height, Bitmap.Config config) {
        Bitmap stitchBmp = Bitmap.createBitmap(width, height, config);

        stitchBmp.copyPixelsFromBuffer(byteBuffer);
        return stitchBmp;
    }

    public static Bitmap bufferToBitmap8888(byte[] bytes, int width, int height) {
        //好像必须ARGB_8888
        Bitmap stitchBmp = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
        //好像必须wrap
        stitchBmp.copyPixelsFromBuffer(ByteBuffer.wrap(bytes));
        return stitchBmp;
    }

    /**
     * Bitmap转化为ARGB数据，再转化为NV21数据
     *
     * @param src    传入的Bitmap，格式为Bitmap.Config.ARGB_8888
     * @param width  NV21图像的宽度
     * @param height NV21图像的高度
     * @return nv21数据
     */
    public static byte[] bitmapToNv21(Bitmap src, int width, int height) {
        if (src != null && src.getWidth() >= width && src.getHeight() >= height) {
            int[] argb = new int[width * height];
            src.getPixels(argb, 0, width, 0, 0, width, height);
            return argbToNv21(argb, width, height);
        } else {
            return null;
        }
    }

    /**
     * ARGB数据转化为NV21数据
     *
     * @param argb   argb数据
     * @param width  宽度
     * @param height 高度
     * @return nv21数据
     */
    private static byte[] argbToNv21(int[] argb, int width, int height) {
        int frameSize = width * height;
        int yIndex = 0;
        int uvIndex = frameSize;
        int index = 0;
        byte[] nv21 = new byte[width * height * 3 / 2];
        for (int j = 0; j < height; ++j) {
            for (int i = 0; i < width; ++i) {
                int R = (argb[index] & 0xFF0000) >> 16;
                int G = (argb[index] & 0x00FF00) >> 8;
                int B = argb[index] & 0x0000FF;
                int Y = (66 * R + 129 * G + 25 * B + 128 >> 8) + 16;
                int U = (-38 * R - 74 * G + 112 * B + 128 >> 8) + 128;
                int V = (112 * R - 94 * G - 18 * B + 128 >> 8) + 128;
                nv21[yIndex++] = (byte) (Y < 0 ? 0 : (Y > 255 ? 255 : Y));
                if (j % 2 == 0 && index % 2 == 0 && uvIndex < nv21.length - 2) {
                    nv21[uvIndex++] = (byte) (V < 0 ? 0 : (V > 255 ? 255 : V));
                    nv21[uvIndex++] = (byte) (U < 0 ? 0 : (U > 255 ? 255 : U));
                }
                ++index;
            }
        }
        return nv21;
    }

    public static ByteBuffer bytesToByteBuffer(byte[] bytes) {
        ByteBuffer byteBuffer = ByteBuffer.allocate(bytes.length);
        byteBuffer.get(bytes);
        return byteBuffer;
    }


    /**
     * RGB 565格式图片转RGB 8888格式图片
     *
     * @param src
     * @return
     */
    public static Bitmap getTransformBitmap(Bitmap src) {
        Bitmap bitmap888 = Bitmap.createBitmap(src.getWidth(), src.getHeight(), Bitmap.Config.RGB_565);
        Canvas canvas = new Canvas(bitmap888);
        canvas.drawBitmap(src, 0, 0, null);
        //save all clip 保存
        canvas.save();
        //stor 存储
        canvas.restore();
        return bitmap888;
    }
}
